#include "clockwidget.h"
ClockWidget::ClockWidget(QWidget *parent) : QWidget(parent) {
    // 设置定时器每秒更新一次时间
    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &ClockWidget::updatetime);
    timer->start(1000);
    player = new QMediaPlayer(this);
    audioOutput = new QAudioOutput;
    player->setAudioOutput(audioOutput);
    audioOutput->setVolume(50);


    //设置ini文件
    //Qt::Tool 取消任务栏图标
    this->setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint |Qt::Tool);
    initSize();

    //闹钟设置窗体
    QString timestr="";
    if(aramDataStatus){
        QStringList hourlist = hourstr.split(";");
        QStringList minulist = minustr.split(";");
        for(int i=0 ;i<hourlist.size(); ++i){
            if(i == 0) {
                timestr = hourlist.at(i)+":"+minulist.at(i);
            }else{
                timestr += ";"+hourlist.at(i)+":"+minulist.at(i);
            }
            //qDebug()<<"hourlist"<<QString::number(i)<<">>"<<hourlist.at(i)<<":"<<minulist.at(i);
        }
    }else{
        timestr = QString::number(armYear) + "-" + QString::number(armMonth)
        + "-" + QString::number(armDate)
            + " " + QString::number(hourAlarm)
            + ":" + QString::number(minuAlarm);
    }
    alarm = new alarmTime(timestr,mp3path,this);
    connect(alarm,&alarmTime::dateTimeChanged,this,&ClockWidget::savealarm);
    connect(alarm,&alarmTime::clearCron,this,&ClockWidget::clearCron);
    connect(alarm,&alarmTime::mp3path,this,&ClockWidget::saveMp3Path);
    connect(alarm,&alarmTime::cronStat,this,&ClockWidget::cronStat);


    //设置托盘
    this->setTrayIcon();
}
//设置闹钟
void ClockWidget::setalarm(){
    this->alarm->show();
}
//清空闹钟
void ClockWidget::clearCron(){
    hourstr = "";
    minustr = "";
    writini("hourAlarm",hourstr,configGroup);
    writini("minuAlarm",minustr,configGroup);
}
//停止闹钟
void ClockWidget::stopalarm(){
    armOpen = false;
    armEnable = false;
    player->stop();
}

//保存闹钟数据
void ClockWidget::savealarm(const QDateTime dateTime){
    // 获取日期部分
    armYear = dateTime.date().year();
    armMonth = dateTime.date().month();
    armDate = dateTime.date().day();

    // 获取时间部分
    hourAlarm = dateTime.time().hour();
    minuAlarm = dateTime.time().minute();
    if(aramDataStatus){
        QString thstr = QString::number(hourAlarm);
        QString tmstr = QString::number(minuAlarm);
        if(hourstr.isEmpty()){
            hourstr = thstr;
        }else{
            hourstr += ";"+thstr;
        }
        if(minustr.isEmpty()){
            minustr = tmstr;
        }else{
            minustr += ";"+tmstr;
        }
        QString::number(hourAlarm);
    }else{
        hourstr = QString::number(hourAlarm);
        minustr = QString::number(minuAlarm);
    }
    //qDebug()<<"hourstr:minustr "<<hourstr<<":"<<minustr;
    writini("armYear",QString::number(armYear),configGroup);
    writini("armMonth",QString::number(armMonth),configGroup);
    writini("armDate",QString::number(armDate),configGroup);
    writini("hourAlarm",hourstr,configGroup);
    writini("minuAlarm",minustr,configGroup);
    writini("aramDataStatus",QString::number(aramDataStatus),configGroup);
}

//保存铃声路径
void ClockWidget::saveMp3Path(const QString path){
    mp3path = path;
    writini("mp3path",mp3path,configGroup);
    player->setSource(QUrl::fromLocalFile(mp3path));
}
//计划每天执行还是单次执行true:每天执行
void ClockWidget::cronStat(bool stats){
    this->aramDataStatus = stats;
}
void ClockWidget::initSize(){
    settings =  new QSettings("clock.ini", QSettings::IniFormat);
    QFileInfo fileInfo(configFile);
    if (fileInfo.exists()){
        // 从文件加载 notes
        r = readini("r",configGroup).toInt();
        fontColor = readini("fontColor",configGroup);
        fontBorderColor = readini("fontBorderColor",configGroup);
        px = readini("px",configGroup).toInt();
        py = readini("py",configGroup).toInt();
        armYear = readini("armYear",configGroup).toInt();
        armMonth = readini("armMonth",configGroup).toInt();
        armDate = readini("armDate",configGroup).toInt();
        hourstr = readini("hourAlarm",configGroup);
        minustr = readini("minuAlarm",configGroup);
        armEnable = readboolini("armEnable",configGroup);
        aramDataStatus = readboolini("aramDataStatus",configGroup);
        mp3path = readini("mp3path",configGroup);
    }else{
        writini("fontColor",fontColor.name(),configGroup);
        writini("fontBorderColor",fontColor.name(),configGroup);
        writini("px",QString::number(px),configGroup);
        writini("py",QString::number(py),configGroup);
        writini("armYear",QString::number(armYear),configGroup);
        writini("armMonth",QString::number(armMonth),configGroup);
        writini("armDate",QString::number(armDate),configGroup);
        writini("hourAlarm",hourstr,configGroup);
        writini("minuAlarm",minustr,configGroup);
        writini("r",QString::number(r),configGroup);
        writboolini("armEnable",armEnable,configGroup);
        writboolini("aramDataStatus",aramDataStatus,configGroup);
        writini("mp3path",mp3path,configGroup);
    }
    player->setSource(QUrl::fromLocalFile(mp3path));
    // 设置窗体为圆形
    setFixedSize(r, r); // 设置固定大小
    setMask(QRegion(this->rect(), QRegion::Ellipse));
    //
    this->setAttribute(Qt::WA_TranslucentBackground);
    // 设置窗口位置
    this->move(px,py);
}
/*
*
*  根据组名GNAME 把KEY,VALUE 写入INI文件
*
*/
void ClockWidget::writini(QString KEY,QString VALUE,QString GNAME)
{
    settings->beginGroup(GNAME);
    settings->setValue(KEY,VALUE);
    settings->endGroup();
    settings->sync();
}
void ClockWidget::writboolini(QString KEY,bool VALUE,QString GNAME)
{
    settings->beginGroup(GNAME);
    settings->setValue(KEY,VALUE);
    settings->endGroup();
    settings->sync();
}
/*
*
*  根据组名GNAME 读取INI文件中的KEY
*
*/
QString ClockWidget::readini(QString KEY,QString GNAME)
{
    QString str;
    settings->beginGroup(GNAME);
    str = settings->value(KEY).toString();
    settings->endGroup();
    return str;
}

bool ClockWidget::readboolini(QString KEY,QString GNAME)
{
    bool str;
    settings->beginGroup(GNAME);
    str = settings->value(KEY).toBool();
    settings->endGroup();
    return str;
}

void ClockWidget::updatetime() {
    // 更新当前时间
    currentTime = QTime::currentTime();
    // 更新时间并重新绘制
    update();
}
void ClockWidget::paintEvent(QPaintEvent *event) {
    QPainter painter(this);
    // painter.setRenderHint(QPainter::Antialiasing);// 抗锯齿
    painter.setRenderHint(QPainter::Antialiasing, true);

    int centerX = width() / 2;
    int centerY = height() / 2;
    int tickLength = centerX / 15; // 刻度线的长度
    int normalTickWidth = tickLength/3; // 普通刻度的线宽
    int boldTickWidth = normalTickWidth * 2; // 加粗刻度的线宽
    int innerRadius = qMin(centerX, centerY) - tickLength * 2; // 表盘外圈的半径
    int sOuter = qMin(centerX, centerY) - tickLength;
    int outerRadius = qMin(centerX, centerY); // 表盘外圈的半径

    fontSize = tickLength * 2;
    // 创建一个 QFont 对象并设置其大小
    QFont font;
    font.setPointSize(fontSize); // 设置字体大小为 12 点
    font.setBold(true);
    // 将字体应用到 QPainter 对象上
    painter.setFont(font);

    // 绘制圆形
    // painter.setPen(fontColor);
    QPen transparentPen(Qt::NoPen); // 不绘制边框
    painter.setPen(transparentPen);
    painter.drawEllipse(centerX - innerRadius, centerY - innerRadius, 2 * innerRadius, 2 * innerRadius);

    // 绘制外部黑色边框
    int borderWidth = tickLength;
    QBrush transparentBrush(Qt::transparent); // 透明填充
    painter.setBrush(transparentBrush);
    QPen Pen(fontBorderColor, borderWidth); // 边框
    Pen.setCapStyle(Qt::SquareCap); // 设置笔帽样式
    painter.setPen(Pen);
    painter.drawEllipse(centerX - sOuter, centerY - sOuter, 2 * sOuter, 2 * sOuter);
    painter.setPen(Qt::NoPen);
    painter.drawEllipse(centerX - outerRadius, centerY - outerRadius, 2 * outerRadius, 2 * outerRadius);




    // 绘制刻度
    for (int i = 0; i < 360; i += 6) {
        double angle = qDegreesToRadians(i);
        int x1 = centerX + innerRadius * qCos(angle);
        int y1 = centerY + innerRadius * qSin(angle);
        int x2 = centerX + (innerRadius - tickLength) * qCos(angle);
        int y2 = centerY + (innerRadius - tickLength) * qSin(angle);


        // 判断是否需要加粗刻度
        int tickWidth = (i == 0 ||
                         i == 30 ||
                         i == 60 ||
                         i == 90 ||
                         i == 120 ||
                         i == 150 ||
                         i == 180 ||
                         i == 210 ||
                         i == 240 ||
                         i == 270 ||
                         i == 300 ||
                         i == 330 ||
                         i == 360) ? boldTickWidth : normalTickWidth;

        // 设置画笔并绘制刻度线
        QPen pen(fontColor, tickWidth);
        painter.setPen(pen);
        painter.drawLine(x1, y1, x2, y2);

    }
    // 绘制整时的刻度上的数字
    for (int i = 10; i < 22; ++i) {
        float angle = -30 * i;
        float x = centerX + (innerRadius - tickLength * 4) * qCos(qDegreesToRadians(angle));
        float y = centerY - (innerRadius - tickLength * 4) * qSin(qDegreesToRadians(angle));
        //矩形宽度
        int r_width = fontSize;
        painter.setPen(fontColor);
        painter.drawText(x - r_width, y - r_width, r_width * 2, r_width * 2, Qt::AlignCenter, QString::number(i - 9));
    }

    // 获取当前日期
    QDate currentDate = QDate::currentDate();
    // 去除字符串开头的前导零
    QString str = currentDate.toString("MM");
    QString dateStr = "";
    if(str.startsWith('0')){
        dateStr = str.remove(0, 1) + "月";
    }else{
        dateStr = str + "月";
    }

    str = currentDate.toString("dd");
    if(str.startsWith('0')){
        dateStr += str.remove(0, 1) + "日";
    }else{
        dateStr += str + "日";
    }

    font.setPointSize(fontSize * 0.7); // 设置字体大小为 12 点
    // 将字体应用到 QPainter 对象上
    painter.setFont(font);
    // 获取字体度量信息
    QFontMetrics metrics(painter.font());
    int textWidth = metrics.horizontalAdvance(dateStr);

    // 计算 x 坐标以在 x 坐标轴上居中显示字符串
    int x = centerX - textWidth / 2;
    int y = centerY + innerRadius/2 ; // 假设 y 是圆心的 y 坐标
    painter.drawText(x ,y,dateStr);
    // 初始化一个QHash来存储星期几的映射关系
    QHash<int, QString> weekdayHash = {
        {1, "星期一"},
        {2, "星期二"},
        {3, "星期三"},
        {4, "星期四"},
        {5, "星期五"},
        {6, "星期六"},
        {7, "星期日"}
    };
    // 获取星期几（整数形式）
    int dayOfWeekInt = currentDate.dayOfWeek();
    QString text = weekdayHash.value(dayOfWeekInt);
    textWidth = metrics.horizontalAdvance(text);

    // 计算 x 坐标以在 x 坐标轴上居中显示字符串
    x = centerX - textWidth / 2;
    y = centerY - innerRadius/3 ; // 假设 y 是圆心的 y 坐标
    painter.drawText(x ,y,text);

    // 绘制时针、分针和秒针，使用 currentTime 变量
    int hourHandLength = innerRadius * 0.5; // 分针长度是半径的70%
    int minuteHandLength = innerRadius * 0.7; // 分针长度是半径的70%
    int secondHandLength = innerRadius * 0.9; // 分针长度是半径的70%

    if(aramDataStatus
        ||(armYear == currentDate.year()
        && armMonth == currentDate.month()
        && armDate == currentDate.day()
        ))
    {
        QStringList hourlist = hourstr.split(";");
        QStringList minulist = minustr.split(";");
        bool forstatus = true;
        for(int i=0 ;i<hourlist.size(); ++i){
            hourAlarm = hourlist.at(i).toInt();
            minuAlarm = minulist.at(i).toInt();
            if( hourAlarm == currentTime.hour()
                && minuAlarm == currentTime.minute()
                )
            {
                if(armOpen){
                    armEnable = true;
                }
                forstatus = false;
                break;
            }
        }
        if(forstatus){
            armOpen = true;
        }
    }
    drawHand(&painter, centerX, centerY, 0, currentTime.second(), secondHandLength, normalTickWidth * 2);
    drawHand(&painter, centerX, centerY, 1, currentTime.minute(), minuteHandLength, normalTickWidth * 3);
    drawHand(&painter, centerX, centerY, 2, currentTime.hour(), hourHandLength, normalTickWidth * 4);
}

/**
 * 参数：
 * int centerX  半径
 * int centerY  半径
 * int value    时间判断：0：秒, 1:分，2：小时
 * int time     时间
 * int length 	指针长度
 * int handWidth  指针宽度
**/
void ClockWidget::drawHand(QPainter *painter, int centerX, int centerY, int value, int time, int length, int handWidth) {
    double angle;
    QColor pointColor = fontColor;
    angle = 90 - time * 6;
    //时
    if(value == 2){
        angle *= 5;
        angle -= currentTime.minute() / 2;
    }
    //分
    if(value == 1){
        angle -= currentTime.second() / 10.00;

        if(armEnable){
            if(armStatus){
                pointColor = Qt::red;
                armStatus = false;
            }else{
                armStatus = true;
            }
            if(player->playbackState() == QMediaPlayer::StoppedState){
                player->play();
                qDebug()<<"start player";
            }
        }

    }
    painter->save();
    painter->setPen(QPen(pointColor, handWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
    painter->drawLine(centerX, centerY,
                      centerX + length * qCos(qDegreesToRadians(angle)),
                      centerY - length * qSin(qDegreesToRadians(angle)));
    painter->restore();
}

void ClockWidget::showContextMenu(const QPoint &pos) {
    QMenu menu(this);
    menu.addAction("时钟大小", this, SLOT(clockSize()));
    menu.addAction("设置颜色", this, SLOT(clockColor()));
    menu.addAction("设置边框颜色", this, SLOT(clockBorderColor()));
    menu.addAction("设置设置闹钟", this, SLOT(setalarm()));
    if(player->playbackState() == QMediaPlayer::PlayingState){
        menu.addAction("停止闹钟",this,SLOT(stopalarm()));
    }
    if(topSatus){
        menu.addAction("取消置顶",this,SLOT(offtop()));
    }else{
        menu.addAction("置顶",this,SLOT(ontop()));
    }
    menu.addAction(version);
    menu.addAction("退出", this, SLOT(onExit()));
    menu.exec(pos); // 在指定位置显示菜单
}

void ClockWidget::onExit(){
    QApplication::quit(); // 退出应用程序
}

void ClockWidget::clockSize(){
    bool ok;
    QString cSize = QInputDialog::getText(nullptr, "设置时钟大小", "输入数字:", QLineEdit::Normal, QString::number(r), &ok);
    if (ok && !cSize.isEmpty()) {
        r = cSize.toInt();
        writini("r",QString::number(r) ,configGroup);
        this->initSize();
    }
}

//设置颜色
void ClockWidget::clockColor(){
    QApplication::setQuitOnLastWindowClosed(false);
    // 显示颜色对话框
    QColorDialog dialog;
    QColor cstr  = dialog.getColor();
    if(cstr.isValid()){
        fontColor = cstr;
        writini("fontColor",fontColor.name(),configGroup);
        //qDebug()<<"save set clolor";
    }
    // qDebug()<<"set clolor";

}
//设置边框颜色
void ClockWidget::clockBorderColor(){

    QApplication::setQuitOnLastWindowClosed(false);
    // 显示颜色对话框
    QColorDialog dialog;
    QColor cstr = dialog.getColor();
    if(cstr.isValid()){
        fontBorderColor = cstr;
        writini("fontBorderColor",fontBorderColor.name(),configGroup);
    }
}

//取消置顶
void ClockWidget::offtop(){
    setWindowFlags(windowFlags() & ~Qt::X11BypassWindowManagerHint);
    // 显示窗口以确保设置生效（如果窗口已隐藏）
    show();
    topSatus = false;
}

void ClockWidget::ontop(){
    // 设置窗口标志以使其保持在最顶层
    setWindowFlags(windowFlags() | Qt::X11BypassWindowManagerHint);
    // 显示窗口以确保设置生效（如果窗口已隐藏）
    show();
    topSatus = true;
}
//设置托盘图标
void ClockWidget::setTrayIcon(){
    // 设置托盘图标
    QString icon = "/opt/apps/com.gitee.xinghuo.clock/icon/clock.png";
    trayIcon->setIcon(QIcon(icon));
    // 设置托盘图标工具提示
    trayIcon->setToolTip(title);
    // 创建上下文菜单
    QMenu *trayIconMenu = new QMenu(this);
    QAction *quitAction = trayIconMenu->addAction("退出");

    // 连接信号和槽
    connect(quitAction, &QAction::triggered, qApp,QCoreApplication::exit);
    connect(trayIcon, &QSystemTrayIcon::activated, this,&ClockWidget::onTrayIconActivated);
    trayIcon->setContextMenu(trayIconMenu);
    trayIcon->show();
}

void ClockWidget::onTrayIconActivated(QSystemTrayIcon::ActivationReason reason) {
    if (reason == QSystemTrayIcon::Trigger) {
        // 当托盘图标被单击时，激活主窗口
        this->activateWindow();
    }
}
